#include "../include/kc.h"
#include "../include/defs.h"
#include "../include/video.h"

/* Apartir de 8 mb */
int nextfree = 8192 * 1024;

int nextshmem = 0x0;

extern int pidActual;
extern int maxmem;
extern void* fs;

int initshmem = 0;

/*
 * system call malloc;
 * 	Next free en principio esta parado en 8mb indica que desde ahí voy
 * a empezar a asignar.
 * 	Nextfree indica el espacio sdiguiente disponible en memoria.
 * que lo voy alineando a 4k.
 * 	Esta funcion esta diseniada solo para llamadas dentro del kernel
 * ya que no tiene sentido que un proc. toque la zona de memoria  del kernel directamente.
 * 	Su pppal uso es en crear los procesos para asignarles el HEAP y luego por
 * mem copy para el fs, en sí mem copy es un wrapper de esta funcion que aumenta restriciones :P
 *
 */
void *
Malloc(int size) {
	void *temp = (void *) nextfree;

	/* alinear a 4k */
	nextfree = nextfree + 2 * size + 4096 - (size % 4096);

	/* si ya era multiplo de 4k ocupe una pagina de mas */
	if (size % 4096 == 0)
		nextfree = nextfree - 4096;

	return temp;
}
/*
 * userMalloc
 * 		Esto te reserva un espacio dentro del heap del proceso.
 * 	Dicho heap fue reservado por "la llamada a sistema" Malloc descripta mas arriba;
 *
 * 		 0x1000
 *
 */
void * processMalloc(int n) {

	process_t *prcPtr;
	prcPtr = GetProcessByPid(pidActual);

	void *toReturn = 0x0;

	/*	print("Heap starts\n");
	 printd(prcPtr->heapstart);
	 print("\n");
	 */
	/*	print("Heap + Size\n");
	 printd(prcPtr->heapstart + prcPtr->heapsize);
	 print("\n");
	 */
	/*	print("(prcPtr->nextfree + n):\n");
	 printd(prcPtr->nextfree + n);
	 print("\n");
	 */

	if ((prcPtr->nextfree + n) < (prcPtr->heapstart + prcPtr->heapsize)) {
		toReturn = (void *) prcPtr->nextfree;
		prcPtr->nextfree += n;
	}/*else{
	 print("no hay memoria");
	 print("me voy a matar");
	 Kill(pidActual);
	 return 0;
	 }*/
	return toReturn;
}

char *
memcpy(const char *srcaddr, char *destaddr, int len) {
	char *dest = destaddr;

	while (len-- > 0) {
	/*	print("src:");
		putchar(*srcaddr);
		print("\n");
*/
		*destaddr++ = *srcaddr++;

	}
/*	print(dest);
	print("dest:");
	printd(dest);
	print("\n");
	*/return dest;
}

void * mem_copy(void * from, void *to, int cant) {

	int i;

	if (cant < 0 || cant > 0x1000) {
		return NULL;
	}

	to = fs;//Malloc(cant);

	//bajarPaginas(GetProcessByPid(pidActual));

	//levantaPaginas(NULL);
	print("estoy en mem_copy 2");
	for (i = 0; i < cant; i++) {
		*((char*) to + i) = *((char*) from + i);
		putchar(*((char*) to + i));
	}
	print("estoy en mem_copy 3");
	//bajarPaginas(NULL); /* deberia bajar las paginas pero no las baja*/

	//levantaPaginas(GetProcessByPid(pidActual));
	return to;
}

/*
 * allocateTerminal.
 * 			Esta funcion basimente reserva memoria
 * 		para las distintas terminales.
 * 			aloca=80*25*2 porque 80 * 25 caracteres
 * 										*2 por los attributoss;
 *
 */

void *
allocteTerminal(int size) {
	int i = 0;
	//  char *temp;
	//   temp = (void *) Malloc (size);

	/* Temp tiene que poseer una direccion dentro de la zona
	 del kernel */
	static char *temp = (char*) 0x300090;
	temp = temp + size;

	while (i < (80 * 25 * 2)) {
		temp[i] = ' ';
		i++;
		temp[i] = 0x07;
		i++;
	};
	/*for (i = 0; i < size; i ++ )
	 {
	 temp[i] = 0;
	 temp[i+1] = 0x07;
	 }
	 */
	return (void *) temp;
}

